#include <jni.h>
#include <string>
#include <iostream>
#include <android/log.h>
#include <libavutil/avutil.h>
//#include <libavutil/avutil.h>





#include "utils/logger.h"
#include "opensl/slplayer.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
} // endof extern "C"
#endif

#define TAG "native-lib"
//#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG,  __VA_ARGS__);
//#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG,  __VA_ARGS__);
//#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG,  __VA_ARGS__);




/**
 * 1、JAVA类的路径和实现jni方法
 */
const char *classPath = "com/fatri/lessionsimple/util/FFmpegNative";
const char *openslNativePath = "com/fatri/lessionsimple/util/OpenSLNative";
SLPlayer *player;
extern "C"
JNIEXPORT jstring JNICALL
ffmpegJniInfo(JNIEnv *jniEnv, jobject thiz) {
    LOGD("CZB", "===ffmpegJniInfo===");
//    const char *version = av_version_info();
    const char *version = "23";
    return jniEnv->NewStringUTF(version);

}


extern "C"
JNIEXPORT jlong JNICALL
createPlayer(JNIEnv *jniEnv, jobject thiz, jstring path, jobject surface) {

    return 0;
}

extern "C"
JNIEXPORT void JNICALL
play(JNIEnv *jniEnv, jobject thiz, jlong player) {

}

extern "C"
JNIEXPORT void JNICALL
stop(JNIEnv *jniEnv, jobject thiz, jlong player) {

}

extern "C"
JNIEXPORT void JNICALL
SLStartPlay(JNIEnv *jniEnv, jobject thiz, jstring path) {
    const char *filePath = jniEnv->GetStringUTFChars(path, 0);
    LOGD("czb", "播放路径:%s", filePath);
    if (player==NULL){
        player=new SLPlayer(filePath);
    }
    player->start();
}
extern "C"
JNIEXPORT void JNICALL
SLStopPlay(JNIEnv *jniEnv, jobject thiz ) {
    if (player!=NULL){
        player->stop();
    } else{
       LOGD("czb","SL player is NULL")
    }
}
/**
 * 2、定义动态注册的JAVA方法的类型和返回类型
 * 该方法返回JNINativeMethod
 * 参数：
 * 1、JAVA方法名
 * 2、描述方法的参数与返回值；具体格式形如“()V”、“(II)V”，其中分为两部分，括号内表示的是参数，括号右侧表示的是返回值；
 * 3、jni实现方法的函数指针
 */
static const JNINativeMethod gMethods[] = {
//        {"setName", "([Ljava/lang/String;)Ljava/lang/String;", (void *) jniSetNames},
        {"version_info", "()Ljava/lang/String;",                        (void *) ffmpegJniInfo},
        {"createPlayer", "(Ljava/lang/String;Landroid/view/Surface;)J", (void *) createPlayer},
        {"play",         "(J)V",                                        (void *) play},
        {"stop",         "(J)V",                                        (void *) stop}
};
static const JNINativeMethod slMethods[] = {
        {"startPlay", "(Ljava/lang/String;)V", (void *) SLStartPlay},
        {"stopPlay", "()V", (void *) SLStopPlay}
};
/**
 * 在JNI生命周期Onload动态注册
 */
JNIEXPORT jint
JNICALL
JNI_OnLoad(JavaVM *javaVm, void *pVoid) {
    LOG_INFO(TAG, "", "===JNI_OnLoad===");
    JNIEnv *jniEnv = nullptr;
    //创建新的jnienv
    jint result = javaVm->GetEnv(reinterpret_cast<void **>(&jniEnv), JNI_VERSION_1_6);
    if (result != JNI_OK) {
        return JNI_ERR;
    }

    jclass mainJclass = jniEnv->FindClass(classPath);
    jniEnv->RegisterNatives(mainJclass, gMethods,
                            sizeof(gMethods) / sizeof(gMethods[0]));//动态注册的数量


    /**
     *  注册opensl相关native方法
     */
    jclass openslNativeClass = jniEnv->FindClass(openslNativePath);
    jniEnv->RegisterNatives(openslNativeClass, slMethods,
                            sizeof(slMethods) / sizeof(slMethods[0]));//动态注册的数量

    return JNI_VERSION_1_6;
}




